package org.zachary.agent.application;

import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service;
import org.zachary.agent.application.exception.NoSuchUserException;
import org.zachary.agent.domain.aggregate_model.token.AccessToken;
import org.zachary.agent.domain.aggregate_model.token.DeviceId;
import org.zachary.agent.domain.aggregate_model.token.RefreshToken;
import org.zachary.agent.domain.aggregate_model.token.Token;
import org.zachary.agent.domain.aggregate_model.user.User;
import org.zachary.agent.domain.repository.TokenRepository;
import org.zachary.agent.domain.repository.UserRepository;
import org.zachary.agent.domain.service.TokenService;
import org.zachary.agent.infrastructure.utils.UUIdUtil;

@Service
public class UserLoginService {
    private final UserRepository userRepository;
    private final TokenService tokenService;
    private final TokenRepository tokenRepository;
    public UserLoginService(final UserRepository userRepository, TokenService tokenService, TokenRepository tokenRepository) {
        this.userRepository = userRepository;
        this.tokenService = tokenService;
        this.tokenRepository = tokenRepository;
    }

    @Transactional
    public Token login(String username, String password,String device) throws Exception {
        User user = userRepository.findByUsername(username);


        if (user == null) {
            throw new NoSuchUserException("用户不存在");
        }
        DeviceId deviceId=new DeviceId(device);
        String userId=user.getUuid();
        AccessToken accessToken = tokenService.generateAccessToken(userId);

        RefreshToken refreshToken=tokenService.generateRefreshToken(userId,deviceId);

        String tokenId=UUIdUtil.createUUId();

        Token token=new Token(
                tokenId,
                userId,
                deviceId,
                accessToken,
                refreshToken
        );
        user.login(password);
        tokenRepository.save(token,userId,deviceId);
        return token;
    }

    @Transactional
    public void logout(String userId,String device) {
        tokenRepository.invalidate(userId,new DeviceId(device));
    }
}
